package controller;

import java.awt.Component;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

/**rappresenta un controller che rileva gli eventi tramite
 * la rilevazione di input/output su un particolare oggetto
 * grafico. Mentre infatti gli AbstractButtonHandlerController basano
 * la loro rivelazione su ActionListener, questo controller basa
 * la rilevazione degli eventi su MouseListener e KeyListener, gli
 * input base a disposizione dell'utente
 * 
 * @author Koldar
 * @version 1.1
 */
public abstract class StandardIOController extends Controller implements MouseListener,KeyListener{

	
	public StandardIOController(){
		super();
	}
	
	/**rimuove il componente dagli interessi di questo Controller
	 * 
	 * @param arg0
	 */
	public void removeStandardIOListener(Component arg0){
		arg0.removeMouseListener(this);
		arg0.removeKeyListener(this);
	}
	/**aggiunge il componente passato come parametro come componente da cui
	 * questo controller rileva gli eventi utente
	 * 
	 * @param arg0 il componente da settare come generatore di eventi
	 */
	public void addStandardIOListener(Component arg0){
		arg0.addMouseListener(this);
		arg0.addKeyListener(this);
	}

	@Override
	public void keyPressed(KeyEvent arg0) {
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
	}

	/*FIXME bug report: non riesco a fare rilevre gli eventi della tastiera al StandardIOCOntroller... chi lo sa perché!
	 * 
	 */
	
	@Override
	public void keyTyped(KeyEvent arg0) {
		switch (arg0.getKeyChar()){
			case KeyEvent.VK_ENTER:{
				this.enterTyped(arg0);
				break;
			}
			case KeyEvent.VK_ESCAPE:{
				this.escTyped(arg0);
				break;
			}
			default: {
				this.unkwnownTyped(arg0);
			}
		}
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		try{
			//viene richiesto di avere il focus da questo componente (se di Component si tratta)
			((Component)arg0.getSource()).requestFocusInWindow();
		}catch (ClassCastException error){
			//la sorgente non può possedere il focus della tastiera
		}
		if (arg0.getButton()==MouseEvent.BUTTON3){//click destro
			this.rightClick(arg0);
			return;
		}
		if (arg0.getButton()==MouseEvent.BUTTON1){//click sinistro
			if (arg0.getClickCount()>=2){
				//double click!
				this.doubleClick(arg0);
				return;
			}
			this.leftClick(arg0);
			return;
		}
		this.unknownClick(arg0);
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
	}

	/**rappresenta la lista di istruzioni da eseguire quando l'utente
	 * clicca due volte velocemente il mouse sull'oggetto ascoltato.
	 * Il click del mouse puo' essere solamente eseguito se il pulsante doubleclicked
	 * e' quello <strong>sinistro</strong>
	 * 
	 * @param arg0 l'evento portatore dei dati
	 */
	public abstract void doubleClick(MouseEvent arg0);
	/**indica la lista di istruzioni da eseguire quando l'utente
	 * preme il tasto sinistro sull'oggetto ascoltato
	 * 
	 * @param arg0 indica l'evento del mouse portatore di informazioni
	 */
	public abstract void leftClick(MouseEvent arg0);
	/**indica la lista di istruzioni che devono essere eseguite quando
	 * l'utente clicca con il pulsante destro del mouse sull'oggetto
	 * ascoltato 
	 * 
	 * @param arg0
	 */
	public abstract void rightClick(MouseEvent arg0);
	/**indica la lista di istruzioni che devono essere qualora l'utente
	 * preme un tasto diverso dal destro e del sinistro del mouse sul componente
	 * ascoltato (come per esempio la rotellina)
	 * 
	 * @param arg0
	 */
	public abstract void unknownClick(MouseEvent arg0);
	/**indica la lista di istruzioni che devono essere eseguite qualora l'utente
	 * preme il tasto INVIO quando l'oggetto ascoltato
	 * ha il focus dell'utente
	 * 
	 * @param arg0
	 */
	public abstract void enterTyped(KeyEvent arg0);
	/**indica la lista di istruzioni che devono essere eseguite quando
	 * l'utente preme il tasto ESC quando l'oggetto ascoltato ha il focus
	 * dell'utente
	 * 
	 * @param arg0
	 */
	public abstract void escTyped(KeyEvent arg0);
	/**indica la lista di istruzioni che devono essere eseguite quando
	 * l'utente ha premuto un tasto diverso da INVIO o ESC durante
	 * il focus dell'utente sull'oggetto ascoltato dal listener
	 * 
	 * @param arg0
	 */
	public abstract void unkwnownTyped(KeyEvent arg0);
}
